#ifndef DATABASEMANAGER_H
#define DATABASEMANAGER_H

#include "sitckcontrol/stickcontrol.h"
#include <QObject>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
struct UserInfo {
    int nPermission=0;
    QString userName;
    QString userPwd;
};

struct WarningInfo {
    QString robotName;
    QString warningTime;
    QString warningText;
};

struct Command {
    int nID = 0;
    int nHexCmd = 0;
    QString strFile = "";
    FUNCTION_KEY nFuncKey = FUNCTION_KEY_NONE;
    STICK_KEY nHotKey = STICK_KEY_NONE;
    QString strShowText = "";
    int nParentID = -1;
    bool operator==(const Command& other) const {
        return nID == other.nID &&
               nHexCmd == other.nHexCmd&&
               strFile == other.strFile&&
               nFuncKey== other.nFuncKey&&
               nHotKey == other.nHotKey&&
               strShowText== other.strShowText&&
               nParentID == other.nParentID;
    }
};
struct AudioFile{
    int nID = 0;
    QString strShowText = "";
    QString strAudioFile = "";
    QString strActionFile = "";
    FUNCTION_KEY nFuncKey = FUNCTION_KEY_NONE;
    STICK_KEY nHotKey = STICK_KEY_NONE;
    bool operator==(const AudioFile& other) const {
        return nID == other.nID &&
               strAudioFile == other.strAudioFile&&
               strActionFile  == other.strActionFile&&
               nFuncKey== other.nFuncKey&&
               nHotKey == other.nHotKey&&
               strShowText== other.strShowText;
    }
};


struct VideoInfo{
    QString strName;
    QString strUrl;
};

struct TeachData
{
    int nID;
    int execTime;
    int waitTime;
    // SportState hexData;
    QVector<float> jointData;
};
struct TeachInfo {
    int nId=0;
    int nRobotID=0;
    QString teachName;
    QString teachJson;
    QVector<TeachData> vTeachData;
};

class Robot;
class DatabaseManager : public QObject
{
    Q_OBJECT
public:
    static DatabaseManager * getInstance();
    bool initDatabase();
    bool login(QString strUser, QString strPwd,int &nRole, QString &strErr);
    bool updatePwd(QString strUser, QString strOldPwd, QString strNewPwd, QString & strErr);

    bool addUser(UserInfo info, QString &strErr);
    bool editUser(UserInfo info,QString strOldUserName, QString &strErr);
    bool deleteUser(QString strUser, QString &strErr);
    QList<UserInfo> getUsers();

    bool addWarning(QString strRobotName,QString warningTime,QString strWarning);//添加告警信息
    QList<WarningInfo> getWarnings();
    bool deleteWarning();//删除告警日志

    bool getRobotList(QList<Robot*> & lsRobot,QString  &strErr);
    bool newRobot(QString strName,
                  QString strUrdfName,
                  QString strSportIP,
                  int nSportPort,
                  QString strPerceptionIP,
                  int nPerceptionrPort,
                  QString strSlamIP,
                  int nSlamPort,
                  QString strSpeakIP,
                  int nSpeakPort,
                  QString strZeroIP,
                  int nZeroPort,
                  QString strTelemetryIP,
                  int nTelemetryPort,
                  int nLeftTool,
                  int nRightTool,
                  int nHeadType,
                  QString strUser,
                  QString strPwd,
                  QList<VideoInfo>lsVideo,
                  int & nID,
                  QString &strErr);
    bool updateRobot(int nID, QString strName,QString strUrdfName,
                     QString strSportIP,
                     int nSportPort,
                     QString strPerceptionIP,
                     int nPerceptionrPort,
                     QString strSlamIP,
                     int nSlamPort,
                     QString strSpeakIP,
                     int nSpeakPort,
                     QString strZeroIP,
                     int nZeroPort,
                     QString strTelemetryIP,
                     int nTelemetryPort,
                     int nLeftTool,
                     int nRightTool,
                     int nHeadType,
                     QString strUser,
                     QString strPwd,
                     QList<VideoInfo>lsVideo,
                     QString &strErr);
    bool deleteRobot(int nID,QString &strErr);

    void setLsWnd(int nRobotID, const QList<int> &newLsWnd);
    QList<int> getLsWnd(int nRobotID);

    bool loadConfig(bool &bShowVritualBtn,bool &bShowJoysticBtn,QString & strTelemetryFolder,  QString &strErr);
    bool setConfig(bool bShowVritualBtn,bool bShowJoystickBtn,QString  strTelemetryFolder,QString &strErr);

    bool getUpperLimbCmd(QList<Command> & lsCmd, QString &strErr);
    bool updateUpperLimbCmd(QList<Command>  &lsCmd, QString &strErr);

    bool getGlobalCmd(QList<Command> & lsCmd, QString &strErr);
    bool updateGlobalCmd(QList<Command>  &lsCmd, QString &strErr);

    bool getAudioFile(QList<AudioFile> &lsFile, QString &strErr);
    bool updateAudioFile(QList<AudioFile>&lsFile, QString &strErr);
    //示教
    bool addTeach(TeachInfo info, QString &strErr);
    bool editTeach(TeachInfo info,QString strOldTeachName, QString &strErr);
    bool deleteTeach(QString strTeachName, QString &strErr);
    bool isTeachNameExist(QString strTeachName);
    QList<TeachInfo> getTeach(int nRobotID);
    QVector<TeachData> JsonToteachData(QString json);

private:
    DatabaseManager(QObject *parent = nullptr);
    ~DatabaseManager();
    DatabaseManager(const DatabaseManager&) = delete;
    DatabaseManager& operator=(const DatabaseManager&) = delete;
    void updataDBtoLeast();

    bool execSql(QSqlQuery & query,QVariantMap mpParam, QString &strErr);

    QSqlDatabase m_db; //数据库连接

    static DatabaseManager * m_pInstance;

};

#endif // DATABASEMANAGER_H
